localport 是OVN的logical switch port的一種特殊類型的port。我們先看一下官方文件對localport的描述。看完是是不是還是無法俱體了解這種類型port的特性呢?今天就讓我們來搞清楚這個port的作用吧。
A localport logical switch port is a special kind of VIF logical switch port. These ports are present in every chassis, not bound to any particular one. Traffic to such a port will never be forwarded through a tunnel, and traffic from such a port is expected to be destined only to the same chassis, typically in response to a request it received.
先來看一下今天要完成的架構長得像圖畫的一樣。先看logical switch,在ls0上,有ls0-ns1、ls0-ns2、ls0-ns3三個port,這裡唯一的不同點,在於ls0-ns3
這個port是屬於localport
類型。因為三個port都在同一個logical switch上,以OVN的觀點來看,ns1、ns2、ns3 三個namespace是可以互相通信。但在二個實體主機上,都有ns3這個namespace,且都有與logical switch上的ls0-ns3做綁定。
現在來看看localport的一些特性:
veth-ns3-br
這個interface綁定到ls0-ns3這個port;而不像ls0-ns1或ls0-ns2這二個port,都只有綁定到某一個主機上的interface。這就是官方文件上說的These ports are present in every chassis, not bound to any particular one
。traffic from such a port is expected to be destined only to the same chassis
。Traffic to such a port will never be forwarded through a tunnel
。但ns1與ns2還是如同之前幾天的說明,是可以透過GENEVE通訊的。這裡可以發現,雖然ns1與ns2都可和ns3通訊,但實際上,和ns1與ns2通訊的ns3明顯不是同一個ns3。ns1與ns2只能與和自己位於同一個hypervisor上的ns3通訊。
和之前一樣,我們先在logical switch上建立logical port。這裡唯一的不同點,在於ls0-ns3
這個port特地把他設定localport
。
ovn-nbctl ls-add ls0
ovn-nbctl lsp-add ls0 ls0-ns1
ovn-nbctl lsp-set-addresses ls0-ns1 "00:00:00:aa:bb:10"
ovn-nbctl lsp-add ls0 ls0-ns2
ovn-nbctl lsp-set-addresses ls0-ns2 "00:00:00:aa:bb:20"
ovn-nbctl lsp-add ls0 ls0-ns3
ovn-nbctl lsp-set-addresses ls0-ns3 "00:00:00:aa:bb:30"
ovn-nbctl lsp-set-type ls0-ns3 localport
再來,分別在controller上將ns1與ns3綁定至logical switch;在hypervisor上,也將ns2與ns3綁定至logical switch。總共做了四次綁定,對應至圖中的四條綠色的線。
#On controller
source helper.sh
add_veth_port ns1 00:00:00:aa:bb:10 10.0.1.10 ls0-ns1
add_veth_port ns3 00:00:00:aa:bb:30 10.0.1.30 ls0-ns3
#On hypervisor
source helper.sh
add_veth_port ns2 00:00:00:aa:bb:20 10.0.1.20 ls0-ns2
add_veth_port ns3 00:00:00:aa:bb:30 10.0.1.30 ls0-ns3
controller上的ns1 和 hypervisor上的ns2可以互相通信,透過tcpdump,也可以再次確認是透過GEVENE實現跨節點通信。
ip netns exec ns1 ping -c 1 10.0.1.20
PING 10.0.1.20 (10.0.1.20) 56(84) bytes of data.
64 bytes from 10.0.1.20: icmp_seq=1 ttl=64 time=1.84 ms
--- 10.0.1.20 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.838/1.838/1.838/0.000 ms
tcpdump -vvneei eth1 'udp port 6081'
01:54:59.014332 52:54:00:4f:17:60 > 52:54:00:69:4b:f4, ethertype IPv4 (0x0800), length 156: (tos 0x0, ttl 64, id 59814, offset 0, flags [DF], proto UDP (17), length 142)
192.168.33.10.51337 > 192.168.33.20.6081: [bad udp cksum 0xc3fa -> 0xe01b!] Geneve, Flags [C], vni 0x13, proto TEB (0x6558), options [class Open Virtual Networking (OVN) (0x102) type 0x80(C) len 8 data 00010002]
00:00:00:aa:bb:10 > 00:00:00:aa:bb:20, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 45506, offset 0, flags [DF], proto ICMP (1), length 84)
10.0.1.10 > 10.0.1.20: ICMP echo request, id 7655, seq 1, length 64
01:54:59.015026 52:54:00:69:4b:f4 > 52:54:00:4f:17:60, ethertype IPv4 (0x0800), length 156: (tos 0x0, ttl 64, id 32053, offset 0, flags [DF], proto UDP (17), length 142)
192.168.33.20.33146 > 192.168.33.10.6081: [bad udp cksum 0xc3fa -> 0x272b!] Geneve, Flags [C], vni 0x13, proto TEB (0x6558), options [class Open Virtual Networking (OVN) (0x102) type 0x80(C) len 8 data 00020001]
00:00:00:aa:bb:20 > 00:00:00:aa:bb:10, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 58297, offset 0, flags [none], proto ICMP (1), length 84)
10.0.1.20 > 10.0.1.10: ICMP echo reply, id 7655, seq 1, length 64
在controller上,ns1可和ns3通信,用tcpdump驗證,並沒有由controller至hypervisor的GENEVE封包產生,所以ns1是和同一個主機上的ns3之通訊。
ip netns exec ns1 ping -c 1 10.0.1.30
PING 10.0.1.30 (10.0.1.30) 56(84) bytes of data.
64 bytes from 10.0.1.30: icmp_seq=1 ttl=64 time=0.456 ms
--- 10.0.1.30 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.456/0.456/0.456/0.000 ms
tcpdump -vvneei eth1 'udp port 6081'
# 無輸出
同理,在hypervisor上,ns2可和ns3通信,用tcpdump驗證,並沒有由controller至hypervisor的GENEVE封包產生,所以ns2是和同一個主機上的ns3之通訊。
ip netns exec ns2 ping -c 1 10.0.1.30
PING 10.0.1.30 (10.0.1.30) 56(84) bytes of data.
64 bytes from 10.0.1.30: icmp_seq=1 ttl=64 time=0.238 ms
--- 10.0.1.30 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.238/0.238/0.238/0.000 ms
tcpdump -vvneei eth1 'udp port 6081'
# 無輸出
在hypervisor上,ns3 無法 和ns1通信,用tcpdump驗證,也沒有發現GENEVE的封包
ip netns exec ns3 ping -c 1 10.0.1.10
PING 10.0.1.10 (10.0.1.10) 56(84) bytes of data.
--- 10.0.1.10 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
tcpdump -vvneei eth1 'udp port 6081'
# 無輸出
同理,在controller上,ns3 無法 和ns2通信,用tcpdump驗證,也沒有發現GENEVE的封包
ip netns exec ns3 ping -c 1 10.0.1.20
PING 10.0.1.20 (10.0.1.20) 56(84) bytes of data.
--- 10.0.1.20 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
tcpdump -vvneei eth1 'udp port 6081'
# 無輸出
今天和大家介紹localport這個功能很特殊的port,想必有人會很好奇,這種port實際的應用場景是什麼。根據OVN文件裡的描述,OpenStack裡的metadata service,就是用localport來完成的。
OpenStack Neutron uses a localport port to serve metadata to VMs.
再來,我們就準備進入到下一個階段,來看一下,在OpenStack的Neutron,是如何透過OVN來完成網路的相關功能。